Weex 渲染页面过程
weex 渲染入口 render()
渲染过程从 WXSDKInstance.render() 开始追溯,render()方法是异步执行渲染工作的。render()重载的方法比较多,此处介绍最基础的一个。
参数代表的含义:
- pageName:用于查看日志,渲染的哪个页面作为标识
- template:加载的本地的或远程的 js(we文件被weex transform后的 js)
- options:配置信息,包括系统版本、app版本、设备信息等
- jsonInitData:用于渲染的初始数据
- flag:监听渲染的时机:
- APPEND_ASYNC:渲染完第一个view后,IWXRenderListener.onViewCreated()调用
- APPEND_ONCE:渲染完整个view tree后,onViewCreated()调用
|
|
接着,渲染工作真正开始于 renderInternal():
|
|
会进行 mRenderContainer 的初始化,RenderContainer 是一个 weex 扩展的 FrameLayout,后期操作,会在这个 container 中添加view元素。
我们接着看 render 过程,WXSDKManager.createInstance() 创建实例:
|
|
此过程中,WXRenderManager 注册实例,实际就是在 mRegistries(map
mBridgeManager 创建实例时,WXModuleManager 会创建 DomModule,由WXDomManager进行创建,sDomModuleMap 存储该 wxSDKInstance 的WXDomModule。
然后,异步执行 invokeCreateInstance(),此过程还会执行 initFramework() 操作。initFramework() 后,会创建出一个 WXJSObject 将 wxsdkinstance相关的数据存储,组成一个数组的形式,传给执行 js 的方法:
|
|
然后,WXBridgeManager 会调用 mWXBridge.execJS() 去调用底层的 C++方法,执行js。
底层C++ 调用Weex Android 功能
我们再来看看 c++ 代码实现的功能,以 callNative() 为例:
|
|
C++ 解析 js 代码后,返回来再调用 weex sdk 的 Android 代码,通过 JNI 提供的反射方式拿到方法的 id,并调用执行。
相对应的,我们找到 Android callNative() 代码:
|
|
Weex native 响应 C++ 的调用
WXBridgeManager.callNative() 对 tasks 进行分发,我们来看看如何分发的:
|
|
分发规则,对 tasks 逐个分类处理:
- 如果是 module:
- 如果 是 dom:执行 WXDomModule.callDomMethod();
- 如果 不是 dom (普通的WXModule) : 执行WXModuleManager.callModuleMethod()
- 如果是 component:
- 调用 WXDomModule.invokeMethod()
task 数据格式(json),如图:
这里只分析第一种情况(其他相似):
WXDomModule.callDomMethod():
会根据 task 的 method 属性分类处理,此处只分析一个:CREATE_BODY:
会继续调用 createBody() 方法,将 wxSDKInstance.id 和 task的args 信息发送给WXDomHandler。
WXDomHandler 的 handleMessage() 中也有很多分类处理,对于WX_DOM_CREATE_BODY:会执行:
具体可参考 WXDomModule、WXDomHandler 类分析
这个时候,就回到我们之前说过的 WXDomStatement 的流程了,WXDomStatement会添加dom 节点(addDomInternal() ),在 addDomInternal 过程中,对dom节点又是一通猛烈的操作:根节点(root节点的准备工作),普通节点(add到父节点下)。
然后,对 dom 对象 进行遍历操作(递归):domObject.traverseTree(),在dom 线程创建 component,生成 component 树(也是递归操作:通过WXRenderStatement.generateComponentTree() )。
对于每个dom节点都会进行 setLayout()、setExtra()、setPadding(),可以去看看compent.setLayout(),就是去使用Android的API 对view进布局和绘制,此处不再贴代码。
总结
- WXBridge 是 Android 与 底层 C++ 的衔接处,Android <=> C++ 的交互,及方法接口都在此类中,的确起到了见名知义的效果
- Weex Android SDK 是使用 Android的API(Java层),实现了view的布局、绘制。并不是依靠 底层so包实现,与IOS的sdk实现方式不同(听同事说……)
- component 处置 weex 的view绘制、布局过程,和Android native处理view的流程十分相似,具体可以参考后面的链接(阿里大神也分析过)